package test.mybatis;

import java.sql.Connection;

import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import test.spring.ExtTransactionSynchronization;


public class DelegateSqlSessionFactory implements SqlSessionFactory {
	
	// private final Log logger = LogFactory.getLog(getClass());
	
	private SqlSessionFactory sqlSessionFactory;
	private ExtTransactionSynchronization extTransactionSynchronization;

	/**
	 * @return
	 * @see org.apache.ibatis.session.SqlSessionFactory#openSession()
	 */
	public SqlSession openSession() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		registerSynchronization();
		return sqlSession;
	}

	/**
	 * @param autoCommit
	 * @return
	 * @see org.apache.ibatis.session.SqlSessionFactory#openSession(boolean)
	 */
	public SqlSession openSession(boolean autoCommit) {
		SqlSession sqlSession = sqlSessionFactory.openSession(autoCommit);
		registerSynchronization();
		return sqlSession;
	}

	/**
	 * @param connection
	 * @return
	 * @see org.apache.ibatis.session.SqlSessionFactory#openSession(java.sql.Connection)
	 */
	public SqlSession openSession(Connection connection) {
		SqlSession sqlSession = sqlSessionFactory.openSession(connection);
		registerSynchronization();
		return sqlSession;
	}

	/**
	 * @param level
	 * @return
	 * @see org.apache.ibatis.session.SqlSessionFactory#openSession(org.apache.ibatis.session.TransactionIsolationLevel)
	 */
	public SqlSession openSession(TransactionIsolationLevel level) {
		SqlSession sqlSession = sqlSessionFactory.openSession(level);
		registerSynchronization();
		return sqlSession;
	}

	/**
	 * @param execType
	 * @return
	 * @see org.apache.ibatis.session.SqlSessionFactory#openSession(org.apache.ibatis.session.ExecutorType)
	 */
	public SqlSession openSession(ExecutorType execType) {
		SqlSession sqlSession = sqlSessionFactory.openSession(execType);
		registerSynchronization();
		return sqlSession;
	}

	/**
	 * @param execType
	 * @param autoCommit
	 * @return
	 * @see org.apache.ibatis.session.SqlSessionFactory#openSession(org.apache.ibatis.session.ExecutorType,
	 *      boolean)
	 */
	public SqlSession openSession(ExecutorType execType, boolean autoCommit) {
		SqlSession sqlSession = sqlSessionFactory.openSession(execType, autoCommit);
		registerSynchronization();
		return sqlSession;
	}

	/**
	 * @param execType
	 * @param level
	 * @return
	 * @see org.apache.ibatis.session.SqlSessionFactory#openSession(org.apache.ibatis.session.ExecutorType,
	 *      org.apache.ibatis.session.TransactionIsolationLevel)
	 */
	public SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level) {
		SqlSession sqlSession = sqlSessionFactory.openSession(execType, level);
		registerSynchronization();
		return sqlSession;
	}

	/**
	 * @param execType
	 * @param connection
	 * @return
	 * @see org.apache.ibatis.session.SqlSessionFactory#openSession(org.apache.ibatis.session.ExecutorType,
	 *      java.sql.Connection)
	 */
	public SqlSession openSession(ExecutorType execType, Connection connection) {
		SqlSession sqlSession = sqlSessionFactory.openSession(execType, connection);
		registerSynchronization();
		return sqlSession;
	}

	/**
	 * @return
	 * @see org.apache.ibatis.session.SqlSessionFactory#getConfiguration()
	 */
	public Configuration getConfiguration() {
		return sqlSessionFactory.getConfiguration();
	}
	
	private void registerSynchronization() {
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			TransactionSynchronizationManager.registerSynchronization(extTransactionSynchronization);
		}
	}

	/**
	 * @param sqlSessionFactory
	 *            the sqlSessionFactory to set
	 */
	public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
		this.sqlSessionFactory = sqlSessionFactory;
	}

	/**
	 * @param extTransactionSynchronization the extTransactionSynchronization to set
	 */
	public void setExtTransactionSynchronization(ExtTransactionSynchronization extTransactionSynchronization) {
		this.extTransactionSynchronization = extTransactionSynchronization;
	}
	
	

}
